﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.Data.SqlClient;
using Clinica_Frba;

namespace Clinica_Frba.UserInterface.ABM.Profesional
{
    public partial class AltaProfesional : Form
    {
        private string string_connection;
        private bool data_checked;
        //private bool personal_data_checked;
        private bool persona_existe;
        private string last_username;

        private List<int> ids_especialidades;

        public AltaProfesional(string conexion)
        {
            InitializeComponent();
            this.string_connection = conexion;
            this.data_checked = false;
            //this.personal_data_checked = false;
            this.passwd_textBox.Enabled = false;
            this.repasswd_textBox.Enabled = false;
            //this.ids_especialidades = new List<int>();
        }

        private void cerrar_btn_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void agregar_espe_btn_Click(object sender, EventArgs e)
        {
            agregar_especialidad altaEspe = new agregar_especialidad(this.string_connection,this);
            altaEspe.Show();
        }

        private string validarCampos()
        {
           
            string messageError = "";
            
            ValidacionesGenericas vg = new ValidacionesGenericas();
            if (this.nombre_textBox.Text.Replace(" ", "") == "")
                messageError += "El campo nombre es obligatorio.\n";
           
           
            if (this.apellido_textBox.Text.Replace(" ", "") == "")
                messageError += "El campo apellido es obligatorio.\n";
            
            
            if (this.mail_textBox.Text.Replace(" ", "") == "")
                messageError += "El campo E-mail es obligatorio.\n";
            else
                if (!vg.email_validation(this.mail_textBox.Text))
                    messageError += "El campo E-mail no es válido.\n";                
                
            if (this.telefono_textBox.Text.Replace(" ", "") != "" && (!vg.esCampoNumerico(this.telefono_textBox.Text) || this.telefono_textBox.Text.Length>14))
                messageError += "El teléfono debe ser un número, sin incluir puntos (.) ni guiones (-) y con una longitud máxima de 15 dígitos.\n"; 
            // para el caso de un numero internacional puede alcanzar esa longitud incluyendo el doble cero delante
             
            if (this.direccion_textBox.Text.Length > 254)            
                messageError += "Longitud excedida en el campo dirección.\n";
            
            if (this.mail_textBox.Text.Length > 254)
                messageError += "Longitud excedida en el campo dirección.\n";
            
            
            if (this.apellido_textBox.Text.Length > 254)
                messageError += "Longitud excedida en el campo apellido.\n";
            
            if (this.nombre_textBox.Text.Length > 254)
                messageError += "Longitud excedida en el campo nombre.\n";

            if (this.matricula_textBox.Text.Replace(" ", "") != "" && (!vg.esCampoNumerico(this.matricula_textBox.Text) || this.matricula_textBox.Text.Length > 18))
                messageError += "El teléfono debe ser un número, sin incluir puntos (.) ni guiones (-) y con una longitud máxima de 18 dígitos.\n";

            if (this.dispo_label.Text != "Disponible")
                messageError += "Debe ingresar un nombre de usuario válido primero.\n";

            if (this.passwd_textBox.Text.Trim() == "")
                messageError += "El campo contraseña es obligatorio.\n";
            else
                if (this.passwd_textBox.Text != this.repasswd_textBox.Text)
                    messageError += "Las contraseñas ingresadas no son iguales.\n";

            return messageError;
        }

        private string getHashedPasswd()
        {
            string passwd = "";


            SHA256 mySHA256 = SHA256Managed.Create();
            byte[] hashValue;

            hashValue = mySHA256.ComputeHash(Encoding.UTF8.GetBytes(this.passwd_textBox.Text));

            for (int i = 0; i < hashValue.Length; i++)
            {
                passwd += String.Format("{0:x2}", hashValue[i]);
            }

            return passwd;
        }

        private void aceptar_btn_Click(object sender, EventArgs e)
        {
            string mensError = this.validarCampos();
            bool camposOk = mensError == "";
            bool error = false;
            
            string queryInsertProfesional = "";
            if (camposOk)
            {
                Dictionary<string, string> camposAinsertar = new Dictionary<string, string>();

                //DATOS DE LA PERSONA:
                if (!this.persona_existe)
                {
                    camposAinsertar["pers_nombre"] = this.nombre_textBox.Text.Trim();
                    camposAinsertar["pers_apellido"] = this.apellido_textBox.Text.Trim();
                    camposAinsertar["pers_dni"] = this.dni_textBox.Text.Trim();
                    camposAinsertar["pers_mail"] = this.mail_textBox.Text.Trim();
                    camposAinsertar["pers_telefono"] = this.telefono_textBox.Text.Trim();
                    camposAinsertar["pers_direccion"] = this.direccion_textBox.Text.Trim();
                    camposAinsertar["pers_fecha_nac"] = this.fecha_nac_dateTimePicker.Value.ToString("MM/dd/yyyy");
                    camposAinsertar["pers_estado_civil"] = this.estado_civil_combobox.Text;
                    if (this.masculino_radioButton.Checked)
                        camposAinsertar["pers_sexo"] = "M";
                    else
                        if (this.femenino_radioButton.Checked)
                            camposAinsertar["pers_sexo"] = "F";


                }
                //DATOS DEL PROFESIONAL

                camposAinsertar["prof_matricula"] = "'" + this.matricula_textBox.Text.Trim() + "'";
                camposAinsertar["prof_username"] = "'" + this.username_textBox.Text.Trim() + "'";
                queryInsertProfesional = "INSERT INTO vacuna_gdd.Profesional(prof_matricula,prof_username,prof_dni_persona)"
                    + " VALUES('" + this.matricula_textBox.Text.Trim() + "','" + this.username_textBox.Text.Trim() + "'," + this.dni_textBox.Text.Trim() + ")";

                string queryObtainID = "SELECT @@IDENTITY";

                string insertEspecialidades = "INSERT INTO vacuna_gdd.profesional_especialidad(ep_especialidad_id,ep_prof_id) VALUES ";

                string insertUsuario = "INSERT INTO vacuna_gdd.usuario(usr_name,usr_passwd) VALUES "
                    + "('" + this.username_textBox.Text.Trim() + "','" + this.getHashedPasswd() + "')";

                string insertUsuarioRol = "INSERT INTO vacuna_gdd.usuario_rol(ur_usr_name,ur_rol_id) VALUES('" + this.username_textBox.Text.Trim() + "',2)";

                using (SqlConnection cn = new SqlConnection(this.string_connection))
                {
                    cn.Open();
                    SqlTransaction tran = cn.BeginTransaction();
                    SqlCommand cmd;
                    try
                    {
                        if (!this.persona_existe)
                        {
                            cmd = new SqlCommand("vacuna_gdd.sp_insertar_persona", cn);
                            cmd.CommandType = CommandType.StoredProcedure;
                            cmd.Parameters.AddWithValue("@nombre", camposAinsertar["pers_nombre"]);
                            cmd.Parameters.AddWithValue("@apellido", camposAinsertar["pers_apellido"]);
                            cmd.Parameters.AddWithValue("@dni", camposAinsertar["pers_dni"]);
                            cmd.Parameters.AddWithValue("@mail", camposAinsertar["pers_mail"]);
                            cmd.Parameters.AddWithValue("@telefono", camposAinsertar["pers_telefono"]);
                            cmd.Parameters.AddWithValue("@direccion", camposAinsertar["pers_direccion"]);
                            cmd.Parameters.AddWithValue("@fecha_nac", this.fecha_nac_dateTimePicker.Text);
                            cmd.Parameters.AddWithValue("@estado_civil", camposAinsertar["pers_estado_civil"]);
                            cmd.Parameters.AddWithValue("@sexo", camposAinsertar["pers_sexo"]);
                            SqlParameter myParam = cmd.Parameters.Add("@dni_a_retornar", SqlDbType.Int, 4);
                            myParam.Direction = ParameterDirection.Output;
                            cmd.Transaction = tran;
                            cmd.ExecuteNonQuery();
                            int id = (int)cmd.Parameters["@dni_a_retornar"].Value;
                            Console.WriteLine("DNI insertado: " + id.ToString());
                        }
                        Console.WriteLine(insertUsuario);
                        cmd = new SqlCommand(insertUsuario, cn);
                        cmd.Transaction = tran;
                        cmd.ExecuteNonQuery();

                        Console.WriteLine(queryInsertProfesional);
                        cmd = new SqlCommand(queryInsertProfesional, cn);
                        cmd.Transaction = tran;
                        cmd.ExecuteNonQuery();

                        cmd = new SqlCommand(queryObtainID, cn);
                        cmd.Transaction = tran;

                        int idProf = Convert.ToInt32(cmd.ExecuteScalar());

                        List<string> idsValues = new List<string>();
                        foreach (int idEspe in ids_especialidades)
                            idsValues.Add("(" + idEspe.ToString() + "," + idProf.ToString() + ")");

                        insertEspecialidades += string.Join(",", idsValues.ToArray());
                        Console.WriteLine(insertEspecialidades);

                        cmd = new SqlCommand(insertEspecialidades, cn);
                        cmd.Transaction = tran;
                        cmd.ExecuteNonQuery();

                        cmd = new SqlCommand(insertUsuarioRol, cn);
                        cmd.Transaction = tran;
                        cmd.ExecuteNonQuery();

                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        Console.WriteLine(ex.Message);
                        MessageBox.Show("Ocurrió un error y no se pudieron insertar los datos. Intentelo nuevamente más tarde.");
                        error = true;
                    }
                    finally
                    {
                        // cerramos la conexion
                        if (cn.State != ConnectionState.Closed)
                            cn.Close();
                        // destruimos la conexion
                        cn.Dispose();
                    }
                }
                
                if (!error)
                    MessageBox.Show("Datos insertados correctamente");
                this.Close();

            }
            else
                MessageBox.Show(mensError);
        }

        private void check_dni_btn_Click(object sender, EventArgs e)
        {
            ValidacionesGenericas vg = new ValidacionesGenericas();
            this.dni_textBox.Text = this.dni_textBox.Text.Trim();
            if (!vg.esCampoNumerico(this.dni_textBox.Text))
            {
                MessageBox.Show("Ingrese un valor numérico (sin puntos)");
                this.dni_textBox.Clear();
            }
            string consultaDNI = "SELECT pers_nombre,pers_apellido,pers_telefono,pers_fecha_nac,pers_direccion, "
                + "pers_sexo,pers_mail,pers_estado_civil FROM vacuna_gdd.Persona WHERE pers_dni=" + this.dni_textBox.Text;
            using (SqlConnection conn = new SqlConnection(this.string_connection))
            {
                SqlCommand cmd = new SqlCommand(consultaDNI, conn);
                try
                {
                    conn.Open();
                    SqlDataAdapter data = new SqlDataAdapter(consultaDNI, conn);
                    DataSet set = new DataSet();
                    data.Fill(set, "tablaprueba");
                    if(set.Tables["tablaprueba"].Rows.Count>0)                    
                    {
                        this.nombre_textBox.Text = set.Tables["tablaprueba"].Rows[0][set.Tables["tablaprueba"].Columns["pers_nombre"]].ToString();
                        this.apellido_textBox.Text = set.Tables["tablaprueba"].Rows[0][set.Tables["tablaprueba"].Columns["pers_apellido"]].ToString();
                        this.direccion_textBox.Text = set.Tables["tablaprueba"].Rows[0][set.Tables["tablaprueba"].Columns["pers_direccion"]].ToString();
                        this.telefono_textBox.Text = set.Tables["tablaprueba"].Rows[0][set.Tables["tablaprueba"].Columns["pers_telefono"]].ToString();
                        this.mail_textBox.Text = set.Tables["tablaprueba"].Rows[0][set.Tables["tablaprueba"].Columns["pers_mail"]].ToString();
                        string estadoCivil = set.Tables["tablaprueba"].Rows[0][set.Tables["tablaprueba"].Columns["pers_estado_civil"]].ToString();
                        this.estado_civil_combobox.SelectedText = estadoCivil;
                        DateTime dt = new DateTime();
                        string datetime_str = set.Tables["tablaprueba"].Rows[0][set.Tables["tablaprueba"].Columns["pers_fecha_nac"]].ToString();
                        if (DateTime.TryParse(datetime_str, out dt))
                            this.fecha_nac_dateTimePicker.Value = dt;
                        string sexo = set.Tables["tablaprueba"].Rows[0][set.Tables["tablaprueba"].Columns["pers_sexo"]].ToString();
                        if (sexo == "M")
                            this.masculino_radioButton.Checked = true;
                        else
                            if (sexo == "F")
                                this.femenino_radioButton.Checked = true;
                        this.persona_existe = true;
                    }
                    else
                    {
                        habilitar_campos_datos_personales();
                        habilitar_campos_datos_gestion_usuarios();
                        habilitar_campos_datos_profesional();
                        this.persona_existe = false;
                      //  this.personal_data_checked = true;
                        this.data_checked = true;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    // cerramos la conexion
                    if (conn.State != ConnectionState.Closed)
                        conn.Close();
                    // destruimos la conexion
                    conn.Dispose();
                }
            }
            // Si todavía no es seguro que no existe el profesional (ya que existe la persona) se procede a precisarlo:
            if(!this.data_checked)
                this.data_checked = !existe_prof();
            if (!this.data_checked)
            {
                MessageBox.Show("Ya existe un profesional con este DNI. Si desea modificar sus datos ingrese al " +
                    "formulario de modificaciones.");
                clear_datos_personales();
            }            
        }

        private bool existe_prof()
        {
            string consulta = "";
            if (this.dni_textBox.Text != "")
            {
                consulta = "SELECT prof_id FROM vacuna_gdd.Profesional WHERE prof_dni_persona=" + this.dni_textBox.Text;
                using (SqlConnection conn = new SqlConnection(this.string_connection))
                {
                    SqlCommand cmd = new SqlCommand(consulta, conn);
                    try
                    {
                        conn.Open();
                        SqlDataAdapter data = new SqlDataAdapter(consulta, conn);
                        DataSet set = new DataSet();
                        data.Fill(set, "tablaprueba");
                        if (set.Tables["tablaprueba"].Rows.Count > 0)
                            return true;
                        else
                            return false;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        return false;
                    }
                    finally
                    {
                        // cerramos la conexion
                        if (conn.State != ConnectionState.Closed)
                            conn.Close();
                        // destruimos la conexion
                        conn.Dispose();
                    }
                }
            }
            else
                return false;            
        }

        private void habilitar_campos_datos_gestion_usuarios()
        {

            this.username_textBox.Enabled = true;
            this.verificar_dispo_btn.Enabled = true;
            
        }

        private void habilitar_campos_datos_profesional()
        {
            this.datos_prof_groupbox.Enabled = true;
            foreach (Control ctrl in this.datos_prof_groupbox.Controls)
            {
                ctrl.Enabled = true;
            }
        }

        private void habilitar_campos_datos_personales()
        {
            this.datos_personales_groupbox.Enabled = true;
            foreach (Control ctrl in this.datos_personales_groupbox.Controls)
            {
                ctrl.Enabled = true;
            }
        }

        private void clear_datos_personales()
        {
            foreach (Control ctrl in this.datos_personales_groupbox.Controls)
            {
                if ((ctrl.GetType() == typeof(TextBox) || ctrl.GetType() == typeof(ComboBox)
                    || ctrl.GetType() == typeof(DateTimePicker) ) && ctrl.Name != "dni_textBox")
                    ctrl.Text = "";
                if (ctrl.GetType() == typeof(RadioButton))
                {
                    RadioButton rb = ctrl as RadioButton;
                    rb.Checked = false;
                }
            }
        }

        private void dni_textBox_TextChanged(object sender, EventArgs e)
        {
            this.clear_datos_personales();
        }

        public void set_ids_especialidades(List<int> ids)
        {            
            this.ids_especialidades = ids;

        }
        public void agregar_especialidades_listBox(object item)
        {
            this.especialidades_listBox.Items.Add(item);
        }

        private void limpiar_espe_btn_Click(object sender, EventArgs e)
        {
            if(this.ids_especialidades!=null)
                this.ids_especialidades.Clear();
            this.especialidades_listBox.Items.Clear();
        }

        private bool valido_usuario()
        {
            string consultaDispo = "";            
            if (this.username_textBox.Text != "" && !this.username_textBox.Text.Contains(' '))
            {
                consultaDispo = "SELECT usr_name FROM vacuna_gdd.usuario WHERE usr_name='" + this.username_textBox.Text + "'";
                using (SqlConnection conn = new SqlConnection(this.string_connection))
                {
                    SqlCommand cmd = new SqlCommand(consultaDispo, conn);
                    try
                    {
                        conn.Open();
                        SqlDataAdapter data = new SqlDataAdapter(consultaDispo, conn);
                        DataSet set = new DataSet();
                        data.Fill(set, "tablaprueba");
                        if (set.Tables["tablaprueba"].Rows.Count > 0)
                            return false;
                        else
                            return true;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        return false;
                    }
                    finally
                    {
                        // cerramos la conexion
                        if (conn.State != ConnectionState.Closed)
                            conn.Close();
                        // destruimos la conexion
                        conn.Dispose();
                    }
                }
            }
            else
                return false;
        }

        private void verificar_dispo_btn_Click(object sender, EventArgs e)
        {

            bool resultado = valido_usuario();
            this.last_username = this.username_textBox.Text;
            if (!resultado)
            {
                this.dispo_label.Text = "No disponible o inválido";
                this.dispo_label.Visible = true;
                this.dispo_label.ForeColor = Color.FromArgb(255, 0, 0);
            }
            else
            {
                this.dispo_label.Text = "Disponible";
                this.dispo_label.Visible = true;
                this.dispo_label.ForeColor = Color.Green;
                this.passwd_textBox.Enabled = true;
                this.repasswd_textBox.Enabled = true;
            }
        }

        private void dispo_no_calculada(object sender, EventArgs e)
        {
            // Veo si cambió el username ingresado, y de ser así anulo la disponibilidad mostrada
            if (this.username_textBox.Text != this.last_username)
            {
                this.dispo_label.Visible = false;
                this.passwd_textBox.Enabled = false;
                this.repasswd_textBox.Enabled = false;
            }
        }

        private void limpiar_datos_personales()
        {
            foreach (Control ctrl in datos_personales_groupbox.Controls)
                if (ctrl.GetType() == typeof(TextBox) || ctrl.GetType() == typeof(ComboBox))
                {                    
                    ctrl.Text = "";
                    ctrl.Enabled = false;
                }
            this.fecha_nac_dateTimePicker.Enabled = false;
            this.dni_textBox.Enabled = true;
            this.matricula_textBox.Text = "";
            this.datos_prof_groupbox.Enabled = false;
            this.masculino_radioButton.Checked = false;
            this.masculino_radioButton.Enabled = false;
            this.femenino_radioButton.Enabled = false;
            this.femenino_radioButton.Checked = false;
            this.passwd_textBox.Text = "";
            this.repasswd_textBox.Text = "";
            this.username_textBox.Text = "";
            this.gestion_usuarios_groupbox.Enabled = false;
        }

        private void limpiar_todo_btn_Click(object sender, EventArgs e)
        {
            if(this.ids_especialidades!=null)
                this.ids_especialidades.Clear();
            this.especialidades_listBox.Items.Clear();
            limpiar_datos_personales();
            

        }
        
       
    }
}
